#include "USART.h"

// 定义接收缓冲区和变量
uint8_t USART_RxBuffer[USART_RX_BUFFER_SIZE];
uint8_t USART_RxCount = 0;
static uint8_t RoomNumber = 0;

/**
 * @brief  配置USART1
 * @param  无
 * @retval 无
 */
void USART_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    // 使能GPIO和USART1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

    // 配置USART1 Tx (PA.09) 为复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1 Rx (PA.10) 为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // USART1配置
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);

    // 配置USART1中断优先级
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // 使能USART1接收中断
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    // 使能USART1
    USART_Cmd(USART1, ENABLE);

    // 清除接收缓冲区
    USART_RxCount = 0;
}

/**
 * @brief  通过USART发送一个字节
 * @param  USARTx: 指定USART接口
 * @param  Data: 要发送的字节
 * @retval 无
 */
void USART_SendByte(USART_TypeDef *USARTx, uint8_t Data)
{
    // 等待发送数据寄存器为空
    while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
        ;

    // 发送数据
    USART_SendData(USARTx, Data);
}

/**
 * @brief  通过USART发送字符串
 * @param  USARTx: 指定USART接口
 * @param  String: 要发送的字符串指针
 * @retval 无
 */
void USART_SendString(USART_TypeDef *USARTx, char *String)
{
    while (*String != '\0')
    {
        USART_SendByte(USARTx, *String);
        String++;
    }
}

/**
 * @brief  获取OpenMV发送过来的房间号
 * @param  无
 * @retval 房间号（1-8）
 */
uint8_t USART_GetRoomNumber(void)
{
    return RoomNumber;
}

/**
 * @brief  USART1中断处理函数
 * @param  无
 * @retval 无
 */
void USART1_IRQHandler(void)
{
    uint8_t temp;

    // 接收中断
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        // 读取接收到的数据
        temp = USART_ReceiveData(USART1);

        // 如果是数字（ASCII码0-9）
        if (temp >= '0' && temp <= '9')
        {
            // 将ASCII码转换为数字
            RoomNumber = temp - '0';

            // 限制房间号范围为1-8
            if (RoomNumber < 1 || RoomNumber > 8)
            {
                RoomNumber = 0; // 无效房间号
            }
        }

        // 存入接收缓冲区
        if (USART_RxCount < USART_RX_BUFFER_SIZE)
        {
            USART_RxBuffer[USART_RxCount++] = temp;
        }

        // 清除中断标志
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

/**
 * @brief  获取接收缓冲区内容
 * @param  无
 * @retval 接收缓冲区指针
 */
char *USART_GetReceiveBuffer(void)
{
    // 确保字符串以\0结尾
    if (USART_RxCount < USART_RX_BUFFER_SIZE)
    {
        USART_RxBuffer[USART_RxCount] = '\0';
    }
    else
    {
        USART_RxBuffer[USART_RX_BUFFER_SIZE - 1] = '\0';
    }

    return (char *)USART_RxBuffer;
}

/**
 * @brief  清空接收缓冲区
 * @param  无
 * @retval 无
 */
void USART_ClearRxBuffer(void)
{
    uint8_t i;

    for (i = 0; i < USART_RX_BUFFER_SIZE; i++)
    {
        USART_RxBuffer[i] = 0;
    }

    USART_RxCount = 0;
}

// 重定向printf函数到USART1
int fputc(int ch, FILE *f)
{
    USART_SendByte(USART1, (uint8_t)ch);
    return ch;
}
